<template>
  <div id="cart">
    <el-table :data="items" max-height="550" @selection-change="handleSelection" empty-text="购物车空空如也~">
      <el-table-column
          type="selection"
          width="55"/>
      <el-table-column label="图片">
        <template v-slot="scope">
          <el-image
              :src="scope.row.img"
              @click.stop.prevent="jump(scope.row.id)"
              class="book-image"
          />
        </template>
      </el-table-column>
      <el-table-column label="商品名称">
        <template v-slot="scope">
          <el-link type="primary" @click.stop.prevent="jump(scope.row.id)">
            {{ scope.row.title }}
          </el-link>
        </template>
      </el-table-column>
      <el-table-column label="单价">
        <template v-slot="scope">
          ￥ {{ scope.row.price.toFixed(2) }}
        </template>
      </el-table-column>
      <el-table-column label="数量">
        <template v-slot="scope">
          <el-input-number
              controls-position="right"
              v-model="scope.row.count"
              :min="1"
              @change="changeCount(scope.row.id, scope.row.count)"/>
        </template>
      </el-table-column>
      <el-table-column label="小计">
        <template v-slot="scope">
          ￥ {{ (scope.row.count * scope.row.price).toFixed(2) }}
        </template>
      </el-table-column>
      <el-table-column label="操作">
        <template v-slot="scope">
          <el-button @click="deleteItem(scope.row.id, scope.$index)" type="text" size="small">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-row type="flex" justify="end" align="middle">
      <el-col :span="1" :pull="10">
        <el-link type="danger" @click="deleteSelected" :disabled="selected.length === 0">删除</el-link>
      </el-col>
      <el-col :span="1">
        <span class="text">地址：</span>
      </el-col>
      <el-col :span="4">
        <el-select
            v-model="address"
            placeholder="--- 请选择 ---"
            no-data-text="还没有地址，快去添加一个吧~"
        >
          <el-option v-for="item in addresses" :key="item.id" :value="item.address"/>
        </el-select>
      </el-col>
      <el-col :span="2">
        <span class="text">已选择 <span style="color: #409eff">{{ selected.length }}</span> 件商品</span>
      </el-col>
      <el-col :span="1">
        <span class="text">总价：</span>
      </el-col>
      <el-col :span="2">
        <span style="font-size: 16pt;color: red;">￥ {{ sumOfSelected.toFixed(2) }}</span>
      </el-col>
      <el-col :span="2">
        <el-button @click="order" type="primary" size="medium" style="height: 40px; margin: 10px 0 10px 0">下单
        </el-button>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import {mapState} from "vuex";
import axios from "axios";

export default {
  name: "CartView",
  data() {
    return {
      items: [],
      selected: [],
      addresses: [],
      address: "",
    }
  },
  methods: {
    jump(id) {
      this.$router.push(`/detail/${id}`)
    },
    changeCount(id, count) {
      axios.post(`/api/cart/edit`, {
        id,
        cnt: count
      })
          .catch(e => {
            if (e.response) {
              this.$message({
                message: `未知的服务器错误 代码${e.response.status}`,
                type: "error"
              });
            } else {
              this.$message({
                message: `未知的错误`,
                type: "error"
              });
            }
          })
    },
    deleteItem(id, index) {
      axios.post(`/api/cart/del`, {id})
          .then(() => {
            if (!index) {
              this.waitForRefresh()
            } else {
              this.items.splice(index, 1)
            }
          })
          .catch(e => {
            if (e.response) {
              this.$message({
                message: `未知的服务器错误 代码${e.response.status}`,
                type: "error"
              });
            } else {
              this.$message({
                message: `未知的错误`,
                type: "error"
              });
            }
          })
    },
    // 获取一本书
    async fetchBook(id) {
      let res = await axios.get(`/api/book/fetch?id=${id}`);
      return res.data
    },
    async fetchCart() {
      let res = await axios.get('/api/cart/show');
      return res.data
    },
    async refresh() {
      let cart = await this.fetchCart();
      let result = []
      for (const i of cart) {
        // i: {
        //     id,
        //     cnt
        // }
        // noinspection EqualityComparisonWithCoercionJS
        if (i.id != 0) {
          let book = await this.fetchBook(i.id)  // 为什么会有id=0的情况存在?
          let item = {
            id: i.id,
            title: book.title,
            price: book.price,
            count: i.cnt,
            img: book.imgUrl
          }
          result.push(item)
        }
      }
      return result
    },
    waitForRefresh() {
      this.refresh()
          .then(
              res => this.items = res
          )
          .catch(e => {
            console.log(e);
            this.$message({
              type: "error",
              message: "未知的错误"
            })
          })
    },
    fetchAddresses() {
      axios.get('/api/address/show')
          .then(res => {
            this.addresses = res.data;
            let defaults = this.addresses.filter(val => val.isDefault)
            if (defaults[0]) {
              this.address = defaults[0].address
            }
          })
    },
    handleSelection(val) {
      this.selected = val
    },
    deleteSelected() {
      let promises = this.selected.map(val => {
        return axios.post(`/api/cart/del`, {id: val.id})
      });
      Promise.all(promises)
          .then(() => {
            this.waitForRefresh();  // 重建购物车列表
          })
          .catch(e => {
            if (e.response) {
              this.$message({
                message: `未知的服务器错误 代码${e.response.status}`,
                type: "error"
              });
            } else {
              this.$message({
                message: `未知的错误`,
                type: "error"
              });
            }
          })
    },
    order() {
      // 构造订单主体
      if (!this.address) {
        this.$alert("请选择收货地址！", {
          type: "error"
        });
        return;
      }
      const orderBody = {
        books: this.selected.map(val => ({
          bookId: val.id,
          cnt: val.count
        })),
        address: this.address
      };
      axios.post('/api/order/add', orderBody)
          .then(() => {
            this.deleteSelected();
            this.$message({
              message: "下单成功！",
              type: "success"
            });
          })
          .catch(e => {
            if (e.response) {
              this.$message({
                message: `未知的服务器错误 代码${e.response.status}`,
                type: "error"
              });
            } else {
              this.$message({
                message: `未知的错误`,
                type: "error"
              });
            }
          })
    }
  },
  computed: {
    sumOfSelected() {
      return this.selected.reduce((p, c) => p + c.price * c.count, 0)
    },
    ...mapState(['username'])
  },
  beforeMount() {
    if (!this.username) {
      this.$router.replace('/')  // 禁止未登录用户访问
      return
    }
    this.waitForRefresh()
    this.fetchAddresses()
  }
}
</script>

<style scoped>
.book-image {
  cursor: pointer;
  height: 80px;
  width: 80px;
}

.text {
  color: #777;
}
</style>